import re
import os.path
import json

from utils import log
from task import Task, find_available_tasks


class Recipe:
    def __init__(self):
        self.title = "noname"
        self.filename = ""
        self.source = ""
        self.task_list = []
        
    def save_as_json(self):
        recipe = {
            'title' : self.title,
            'source': self.source,
            'tasks' : [{ 
                  'id' : task.id,
                  'speech' : task.speech,
                  'query' : task.query,
                  'dep' : [t.id for t in task.dependencies],
                  'dur' : task.duration,
                 } for task in self.task_list]
            }
        filename = os.path.splitext(self.filename)[0]+'.json'
        json.dump(recipe, open(filename,'w'), indent=4)
        
    @staticmethod
    def parse_file(fn):
        log("Parsing file %s" % fn)
        # read the file lines
        with open(fn,'r') as f:
            ls= f.readlines()
            
        recipe = Recipe()
        recipe.filename = fn
        td={}  # a task dictionary: values are tasks and keys are their IDs
        last_task = None
        
        for line_num, l in enumerate(ls):
            # prepare for parsing (trim comment, split on space, colon, comma)
            s=re.sub('[ \t\r\n\v\f,:]+',':',l.strip().partition('#')[0]).split(':')
            # decide what to do with the line
            if not s or not s[0]:
                continue
            if s[0]=='title':
                recipe.title = " ".join(s[1:])
            elif s[0] == 'source':
                recipe.source = " ".join(s[1:])
            elif s[0]=='task':
                last_task = Task(s[1], len(recipe.task_list))
                recipe.task_list.append(last_task)
                td[s[1]]= last_task
            elif s[0]=='depends_on':
                for v in s[1:]:
                    last_task.dependencies.append(td[v])
            elif s[0]=='duration':
                last_task.duration=int(s[1])
            elif s[0] in ['speech','query']:
                setattr(last_task, s[0], ' '.join(s[1:]))
            else:
                # unexpected!
                log("Unexpected token in line %d: [%s]" % (line_num+1, " ".join(s)))
                continue
        return recipe

    @staticmethod
    def parse_json_file(fn):
        log("Parsing file %s" % fn)
        
        json_data = json.load(open(fn))
        recipe = Recipe()
        recipe.source = json_data.get('source', '')
        recipe.title = json_data['title']
        recipe.filename = fn
        recipe.task_list = []
        td={}  # a task dictionary: values are tasks and keys are their IDs
        for t_data in json_data['tasks']:
            task = Task(t_data['id'], len(recipe.task_list))
            task.speech = t_data.get('speech','')
            task.query = t_data.get('query', '')
            task.dependencies = t_data['dep']
            task.duration = t_data['dur']
            td[t_data['id']] = task
            recipe.task_list.append(task)
        for task in recipe.task_list:
            task.dependencies = [td[dep_id] for dep_id in task.dependencies]
        
        return recipe
    
   

if __name__ == "__main__":
    recipe = parse_file('healthy_baked_chicken_nuggets.txt')
    ta = recipe.task_list
    ts= find_available_tasks(ta)
    print 'number of tasks                                      :',len(ta)
    print 'speech of first task without uncompleted dependencies:',ts[0].speech
    print 'number of tasks without uncompleted dependencies     :',len(ts)



 